package com.CmJava.crowd.service.imp;

import com.CmJava.crowd.entity.ResultEntity;
import com.CmJava.crowd.entity.Email;
import org.springframework.stereotype.Service;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.search.FlagTerm;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;


@Service
public class EmailServiceImp implements com.CmJava.crowd.service.EmailService {

    @Override
    public ResultEntity checkLoginEmail(String sendHost, String password) throws MessagingException {
        Session session = getSession(sendHost,password);
        //创建邮件消息，发送邮件,因为是验证登录，所以发给自己
        Message message =getTextMessage(sendHost,sendHost,"后台管理系统邮箱登录通知","后台管理系统邮箱已登录",session);
        //建立发送邮件的对象
        Transport sender = session.getTransport();
        Transport.send(message); // 授权码
        return null;
    }

    @Override
    public ResultEntity sendTextEmail(String sendHost,String password,String recipientHost,String subject,String textMessage) throws MessagingException {
        Session session = getSession(sendHost,password);
        Message message =getTextMessage(sendHost,recipientHost,subject,textMessage,session);
        //建立发送邮件的对象
        Transport sender = session.getTransport();
        Transport.send(message);
        return null;
    }

    @Override
    public ResultEntity sendHtmlEmail(String sendHost,String password,String recipientHost,String subject,String htmlMessage) {
        return null;
    }

    @Override
    public ResultEntity sendFileEmail(String sendHost,String password,String recipientHost,String subject,String fileMessage) {
        return null;
    }


    //返回session对象
    private Session getSession(String sendHost,String password){
        Properties props = System.getProperties();
        // 这里写死了，仅支持qq邮箱
        props.setProperty("mail.smtp.host", "smtp.qq.com");
        props.setProperty("mail.smtp.auth", "true");
        props.setProperty("mail.transport.protocol", "smtp");
        Session session = Session.getInstance(props, new Authenticator() {
            // 发件人的授权，new PasswordAuthentication(userName，password)
            // userName:发件人邮箱
            // password：发件人邮箱授权码
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(sendHost,password);
            }
        });
        //控制台输出发送情况
        session.setDebug(true);
        return session;
    }

    // 返回消息对象
    private Message getTextMessage(String sendHost,String recipientHost,String subject,String text,Session session) throws MessagingException {
        //创建邮件消息，发送邮件
        Message message = new MimeMessage(session);
        //设置发件人邮箱
        message.setFrom(new InternetAddress(sendHost));

        // To: 收件人
        // message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(toRecipient));
        message.setRecipients(MimeMessage.RecipientType.TO, InternetAddress.parse(recipientHost, false));
        // To: 增加收件人（可选）
        // message.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress(toRecipient);
        // Cc: 抄送（可选）
        // message.setRecipient(MimeMessage.RecipientType.CC, new InternetAddress(ccRecipient));
        // Bcc: 密送（可选）
        // message.setRecipient(MimeMessage.RecipientType.BCC, new InternetAddress(bccRecipient));

        message.setSentDate(new Date());
        message.setSubject(subject); // 邮件标题
        message.setText(text); // 邮件内容
        message.saveChanges();
        return message;
    }

    @Override
    public ResultEntity getEmail(String sendHost, String password) {
        // imap服务器端口
        String port = "143";
        // 服务器地址,这里我写死了，仅仅支持qq邮箱
        String imapServer = "imap.qq.com";
        String protocol = "imap";

        //有些参数可能不需要
        Properties props = new Properties();
//        props.setProperty("mail.imap.socketFactory.class", SSL_FACTORY);
//        props.setProperty("mail.imap.socketFactory.fallback", "false");
        props.setProperty("mail.transport.protocol", protocol); // 使用的协议
        props.setProperty("mail.imap.port", port);
//        props.setProperty("mail.imap.socketFactory.port", port);

        // 获取连接
        Session session = Session.getDefaultInstance(props);
        session.setDebug(false);

        Store store=null;
        Folder folder=null;
        ResultEntity<Email> emailResultEntity = new ResultEntity<>();

        // 获取Store对象
        try {


        store = session.getStore(protocol);

        store.connect(imapServer, sendHost, password); // 登陆认证

        // 通过imap协议获得Store对象调用这个方法时，邮件夹名称只能指定为"INBOX"
        folder = store.getFolder("INBOX");// 获得用户的邮件帐户
        folder.open(Folder.READ_WRITE); // 设置对邮件帐户的访问权限

        int unreadMessageCount = folder.getUnreadMessageCount();// 得到未读数量


        FlagTerm ft = new FlagTerm(new Flags(Flags.Flag.SEEN), false); // false代表未读，true代表已读

        // email对象中创建了对应数量的emailUnit数组
        Email email = new Email(unreadMessageCount);
        Email.emailUnit[] emailUnitArray = email.getEmailUnit();
        int conut=0;

        // 获取未读的信息
        Message messages[] = folder.search(ft);
        for (Message message : messages) {
//            Object content = message.getContent();
//            if (!(content instanceof String)){
//                continue;
//            }

            Email.emailUnit emailUnit = emailUnitArray[conut];

            String subject = message.getSubject();// 获得邮件主题
            if(subject.contains("后台管理系统邮箱")){
                // 主题是“后台管理系统邮箱” ,也是放进email对象里，到时候前端页面不要去显示它
                emailUnit.setSubject(subject);
                conut++;
                if (conut>=unreadMessageCount){
                    break;
                }
                continue;
            }
            emailUnit.setSubject(subject);
            Address from = (Address) message.getFrom()[0];// 获得发送者地址
            String sendAddressAll = from.toString().split("<")[1];
            int length = sendAddressAll.length();
            String sendAddress = sendAddressAll.substring(0, length - 1);
            emailUnit.setAddress(sendAddress);
            //获取发件日期
            Date sendDate1 = message.getSentDate();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sendDate = simpleDateFormat.format(sendDate1);
            emailUnit.setDate(sendDate);
            emailUnit.setUnread(0);

            /*
                Enumeration headers = message.getAllHeaders();
                System.out.println("----------------------allHeaders-----------------------------");
                while (headers.hasMoreElements()) {
                    Header header = (Header)headers.nextElement();
                    System.out.println(header.getName()+" ======= "+header.getValue());
                    System.out.println("----------------------------");
                }
            */

            parseMultipart((Multipart) message.getContent(), emailUnit);
            //imap读取后邮件状态会变为已读,这里设为未读，就是不改变邮箱里面邮件的状态
            message.setFlag(Flags.Flag.SEEN, false);

            conut++;
            if (conut>=unreadMessageCount){
                break;
            }
        }

        emailResultEntity.setResultFlag(true);
        emailResultEntity.setData(email);
        emailResultEntity.setMessage(null);
        return emailResultEntity;

        }catch (Exception e){
            e.printStackTrace();
            return ResultEntity.failWithoutMessage();
        }finally {
            try {
                if (folder!=null){
                    folder.close(false);// 关闭邮件夹对象
                }
            } catch (MessagingException e) {
                e.printStackTrace();
            }
            try {
                if (store!=null) {
                    store.close(); // 关闭连接对象
                }
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public ResultEntity readedThisEmail(String sendHost, String password, String address, String subject, String date) {
        String port = "143";
        String imapServer = "imap.qq.com";
        String protocol = "imap";
        Properties props = new Properties();
        props.setProperty("mail.transport.protocol", protocol); // 使用的协议
        props.setProperty("mail.imap.port", port);

        // 获取连接
        Session session = Session.getDefaultInstance(props);
        session.setDebug(false);

        Store store=null;
        Folder folder=null;

        // 获取Store对象
        try {
            store = session.getStore(protocol);
            store.connect(imapServer, sendHost, password); // 登陆认证

            // 通过imap协议获得Store对象调用这个方法时，邮件夹名称只能指定为"INBOX"
            folder = store.getFolder("INBOX");// 获得用户的邮件帐户
            folder.open(Folder.READ_WRITE); // 设置对邮件帐户的访问权限

            FlagTerm ft = new FlagTerm(new Flags(Flags.Flag.SEEN), false); // false代表未读，true代表已读

            // email对象中创建了对应数量的emailUnit数组


            // 获取未读的信息
            Message messages[] = folder.search(ft);
            for (Message message : messages) {
                String subject0 = message.getSubject();// 获得邮件主题
                Address from = (Address) message.getFrom()[0];// 获得发送者地址
                String sendAddressAll = from.toString().split("<")[1];
                int length = sendAddressAll.length();
                String sendAddress = sendAddressAll.substring(0, length - 1);
                //获取发件日期
                Date sendDate1 = message.getSentDate();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String sendDate = simpleDateFormat.format(sendDate1);
                if (address.equals(sendAddress) && subject.equals(subject0) && date.equals(sendDate)) {
                    //将对应的邮件设为已读
                    message.setFlag(Flags.Flag.SEEN, true);
                }
            }
            return ResultEntity.successWithoutData();

        }catch (Exception e){
            e.printStackTrace();
            return ResultEntity.failWithoutMessage();
        }finally {
            try {
                if (folder!=null){
                    folder.close(false);// 关闭邮件夹对象
                }
            } catch (MessagingException e) {
                e.printStackTrace();
            }
            try {
                if (store!=null) {
                    store.close(); // 关闭连接对象
                }
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }
    }

//    protected static String decodeText(String text) throws UnsupportedEncodingException {
//        if (text == null)
//            return null;
//        if (text.startsWith("=?GB") || text.startsWith("=?gb"))
//            text = MimeUtility.decodeText(text);
//        else
//            text = new String(text.getBytes("ISO8859_1"));
//        return text;
//    }


    /**
     * 对复杂邮件的解析
     * @param multipart
     * @throws MessagingException
     * @throws IOException
     */
    public static void parseMultipart(Multipart multipart,Email.emailUnit emailUnit) throws MessagingException, IOException {
        // count 邮件正文的可解析类型数，留着先不用
        int count = multipart.getCount();

        // 这里直接写死，只获取文本邮件，先忽略html和file邮件
        for (int idx=0;idx<count;idx++) {
            BodyPart bodyPart = multipart.getBodyPart(idx);

            if (bodyPart.isMimeType("text/plain")) {
                //如果是文本邮件
                // 获取文本内容编码
                String contentType = bodyPart.getContentType();
                int index = contentType.indexOf("=");
                String charset = contentType.substring(index + 1);
                // 获取文本内容
                String content = (String) bodyPart.getContent();
                emailUnit.setTextMessage(content);

            } else if(bodyPart.isMimeType("text/html")) {

            } else if(bodyPart.isMimeType("multipart/*")) {
//                Multipart mpart = (Multipart)bodyPart.getContent();
//                parseMultipart(mpart);

            } else if (bodyPart.isMimeType("application/octet-stream")) {
//                String disposition = bodyPart.getDisposition();
//                System.out.println(disposition);
//                if (disposition.equalsIgnoreCase(BodyPart.ATTACHMENT)) {
//                    String fileName = bodyPart.getFileName();
//                    InputStream is = bodyPart.getInputStream();
//                    copy(is, new FileOutputStream("D:\\"+fileName));
//                }
            }
        }
    }

    /**
     * 文件拷贝，在用户进行附件下载的时候，可以把附件的InputStream传给用户进行下载
     * @param is
     * @param os
     * @throws IOException
     */
//    public static void copy(InputStream is, OutputStream os) throws IOException {
//        byte[] bytes = new byte[1024];
//        int len = 0;
//        while ((len=is.read(bytes)) != -1 ) {
//            os.write(bytes, 0, len);
//        }
//        if (os != null)
//            os.close();
//        if (is != null)
//            is.close();
//    }
}
